package com.custom.service;

import com.custom.contants.Constants;
import com.custom.model.MessageModel;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import java.sql.SQLException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * @author wh
 * @Description
 * @date 2018/4/4 15:54
 */
@Service
public class CustomeData {
    public String getSql(Object object) {
        MessageModel message = (MessageModel) object;
        String sql = null;

        if (Constants.tables == null || Constants.tables.indexOf(message.getTable()) == -1) {
            return null;
        }
        HashMap<Object, Object> data = (HashMap<Object, Object>) message.getMessage();

        ConcurrentHashMap<Object, Object> metamap = Constants.mateMaps.get(message.getTable());
        ConcurrentHashMap<Object, Object> handlemap = new ConcurrentHashMap<Object, Object>();
        try {
            for (Map.Entry<Object, Object> entry : data.entrySet()) {
                try {
                    handleNULL(metamap, entry, handlemap);
                } catch (Exception e) {
                    e.printStackTrace();
                    continue;
                }
            }

            sql = handleSQL(handlemap, message);
        } catch (Exception e) {
            e.printStackTrace();
        }

        return sql;
    }

    /**
     * 纯string类型的json字符串需要判断非String类型数据是否为空
     * @param metamap 数据库字段对应类型信息
     * @param entry
     * @param handlemap 需要特殊处理的字段
     * @throws ParseException
     */
    private void handleNULL(ConcurrentHashMap<Object, Object> metamap, Map.Entry<Object, Object> entry, ConcurrentHashMap<Object, Object> handlemap) throws ParseException {
        if ((metamap.get(entry.getKey()).toString().equalsIgnoreCase("int") || metamap.get(entry.getKey()).toString().equalsIgnoreCase("decimal")
                || metamap.get(entry.getKey()).toString().equalsIgnoreCase("tinyint") || metamap.get(entry.getKey()).toString().equalsIgnoreCase("bigint")
                || metamap.get(entry.getKey()).toString().equalsIgnoreCase("double")) && "".equals(String.valueOf(entry.getValue()).trim())) {
            handlemap.put(entry.getKey(), "needhandle");
        } else if (metamap.get(entry.getKey()).toString().equalsIgnoreCase("datetime") || metamap.get(entry.getKey()).toString().equalsIgnoreCase("timestamp")) {
            if ("".equals(entry.getValue())) {
                handlemap.put(entry.getKey(), "needhandle");
            } else {
                SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yy-MM-dd HH:mm:ss");
                Date date = simpleDateFormat.parse(entry.getValue().toString());
                Calendar calendar = Calendar.getInstance();
                calendar.setTime(date);
                handlemap.put(entry.getKey(), "'" + simpleDateFormat.format(calendar.getTime()) + "'");
            }
        } else if ("".equals(String.valueOf(entry.getValue()).trim())) {
            handlemap.put(entry.getKey(), "needhandle");
        } else {
            handlemap.put(entry.getKey(), "'" + entry.getValue() + "'");
        }
    }


    /**
     * 拼接sql语句
     * @param handlemap 需要特殊处理的字段
     * @param message 传入的原始数据信息
     * @return
     */
    private String handleSQL(ConcurrentHashMap<Object, Object> handlemap, MessageModel message) {
        StringBuffer key = new StringBuffer();
        StringBuffer value = new StringBuffer();
        StringBuffer update = new StringBuffer();
        StringBuffer where = new StringBuffer();
        StringBuffer sql = new StringBuffer();

        for (Map.Entry<Object, Object> entry : handlemap.entrySet()) {
            if ("needhandle".equals(entry.getValue())) {
                continue;
            } else {
                key.append(entry.getKey() + ",");
                value.append(entry.getValue() + ",");
                if (Constants.primaryKeys.get(message.getTable()).indexOf(entry.getKey()) == -1) {
                    update.append(entry.getKey() + "=" + entry.getValue() + ",");
                } else if ("update".equalsIgnoreCase(message.getAction()) || "delete".equalsIgnoreCase(message.getAction())) {
                    where.append(entry.getKey() + "=" + entry.getValue() + "and");
                }
            }
        }

        key = new StringBuffer(key.substring(0, key.length() - 1));
        value = new StringBuffer(value.substring(0, value.length() - 1));
        update = new StringBuffer(update.substring(0, update.length() - 1));
        where = StringUtils.isEmpty(where)? new StringBuffer("") : new StringBuffer(where.substring(0, where.length() - 3));


        if ("update".equalsIgnoreCase(message.getAction())) {
            sql = sql.append("update " + message.getTable() + " set " + update + " where ").append(where);
        }
        else if ("insert".equalsIgnoreCase(message.getAction())) {
            sql = sql.append("insert into " + message.getTable() + " (").append(key).append(") values( ").append(value).append(")");
        }
        else if ("delete".equalsIgnoreCase(message.getAction())) {
            sql = sql.append("delete from " + message.getTable() + " where ").append(where);
        }

        return sql.toString();
    }
}